# -*- coding: utf-8 -*-
"""
Module Description: 负责在进程启动时，建立各适配器和模型的关联
"""

import framework.dal.dbmodel as dbmdls
import framework.dal.profile_model as pcmdls
import character_adapters as adts
import cross_adapters as crossadts
import profile_adapters as pdts
import center_adapters as centeradts
from framework.dal.dal_manager import (
    PeeweeDALDescriptor,
    TransactionDelegator, PeeweeTransaction
)
from framework.dal.transaction import Transaction


DATA_LAYER_PEEWEE = 'peewee'
DATA_LAYER_CHAOS = 'chaos'


# 引入peewee数据表模型, 这一行避免ide自动移除未使用的导入
dbmdls = dbmdls


# 根据dal_mode选择数据层实现
USE_DATA_LAYER = DATA_LAYER_PEEWEE

# 适配器和模型的关联
# 适配器类: (数据源名称, 模型名称)
# 使用一致的命名生成模型和适配器名字并放在指定文件,即可自动生成profile_register_setting和character_register_setting

# 配置数据相关
# 重要！！！
# 配置表一定要定义PrimaryKey字段，
# 否则Peewee会自动创建'id'字段，
# 若存在'id'或'ID'或'Id'或'iD'
# 会在建表阶段报DuplicateColumn错误
profile_register_setting = {
    # Adapter: (TableName,),
    # pdts.ConfigEnvSetAdapter: ('ConfigEnvSet',),
}

# 角色数据相关
character_register_setting = {
    # Adapter: (TableName,),
    # adts.RoleAdapter: ('TbRole',),
}


def translate_adapter_name_to_table_name(adapter_name, is_profile=False):
    """
    转换表适配器名称为对应的角色表名称
    :param adapter_name: 表适配器名称
    :param is_profile: 是否tc配置表
    :return: string
    """
    if is_profile:
        return adapter_name[:-len('Adapter')]
    return 'Tb' + adapter_name[:-len('Adapter')]


def translate_character_adapter_name_to_table_name(character_adapter_name):
    """
    转换角色表适配器名称为对应的角色表名称
    :param character_adapter_name: 角色表适配器名称
    :return: string
    """
    return 'Tb' + character_adapter_name[:-len('Adapter')]


def register_all_adapters():
    """
    注册所有模型适配器

    注册的模型包括:
    - 配置数据模型
    - 各种范围的角色数据模型

    发生的修改主要有:
    - 初始化*_register_setting字典,保存所有模型类的映射
    - 注入模型适配器的objects和model_class属性
    """
    # 配置数据模型
    for elem_name in dir(pdts):
        if elem_name == 'BaseAdapter' or not elem_name.endswith('Adapter'):
            continue
        adapter = getattr(pdts, elem_name)
        mdl_name = translate_adapter_name_to_table_name(elem_name, is_profile=True)
        if not hasattr(pcmdls, mdl_name):
            continue

        # 内存配置模式(peewee.sqlite(:memory:))
        adapter.model_class = getattr(pcmdls, mdl_name)
        adapter.objects = PeeweeDALDescriptor()

        # 写入profile_register_setting值
        profile_register_setting[adapter] = (mdl_name,)

    # 角色数据模型
    character_mdls = dbmdls
    dal_descriptor = PeeweeDALDescriptor

    for elem_name in dir(adts):
        if elem_name == 'BaseAdapter' or not elem_name.endswith('Adapter'):
            continue
        adapter = getattr(adts, elem_name)
        mdl_name = translate_character_adapter_name_to_table_name(elem_name)

        if not hasattr(character_mdls, mdl_name):
            continue

        adapter.model_class = getattr(character_mdls, mdl_name)
        adapter.objects = dal_descriptor()

        # 写入character_register_setting值
        character_register_setting[adapter] = (mdl_name,)


def register_transaction_delegator():
    """注册事务对象"""

    TransactionDelegator.set_transaction_class(PeeweeTransaction)


register_all_adapters()
register_transaction_delegator()


if __name__ == '__main__':
    print character_register_setting
    print profile_register_setting
